// AStarPatchFinderView.cpp : implementation of the CAStarPatchFinderView class
//

#include "stdafx.h"
#include "AStarPatchFinder.h"

#include "AStarPatchFinderDoc.h"
#include "AStarPatchFinderView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

inline BOOL key_down(int key)
{
	return BOOL(GetAsyncKeyState(key) & 0x8000);
}
// CAStarPatchFinderView

IMPLEMENT_DYNCREATE(CAStarPatchFinderView, CView)

BEGIN_MESSAGE_MAP(CAStarPatchFinderView, CView)
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

// CAStarPatchFinderView construction/destruction

CAStarPatchFinderView::CAStarPatchFinderView()
{
	// TODO: add construction code here
	offset_.SetPoint(0, 0);
	start_point_.SetPoint(0, 0);
}

CAStarPatchFinderView::~CAStarPatchFinderView()
{
}

BOOL CAStarPatchFinderView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

// CAStarPatchFinderView drawing

void CAStarPatchFinderView::OnDraw(CDC* pDC)
{
	CAStarPatchFinderDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	if (!pDC->IsPrinting())
	{
 		CRect rcClient, rcMap;
 		GetClientRect(rcClient);
 		
 		rcMap = rcClient;
 		if (!game_map_.is_empty())
 		{
 			rcMap.bottom = game_map_.get_height();
 			rcMap.right = game_map_.get_width();
 		}
 		CDC MemDC; 
 		CBitmap MemBitmap;
 		MemDC.CreateCompatibleDC(NULL);
 		MemBitmap.CreateCompatibleBitmap(pDC, rcMap.Width(), rcMap.Height());
 		CBitmap *pOldBMP = MemDC.SelectObject(&MemBitmap);
 		MemDC.FillSolidRect(0, 0, rcMap.Width(), rcMap.Height(), RGB(127, 127, 127));
 		{
 			if (!game_map_.is_empty())
 			{
				picture_.Render(&MemDC, rcMap);
 			//	game_map_.DrawMap(&MemDC);
 			}
 		}
 		pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &MemDC, offset_.x, offset_.y, SRCCOPY);
 		MemDC.SelectObject(pOldBMP);
 		MemBitmap.DeleteObject();
 		MemDC.DeleteDC();
	}
}


// CAStarPatchFinderView diagnostics

#ifdef _DEBUG
void CAStarPatchFinderView::AssertValid() const
{
	CView::AssertValid();
}

void CAStarPatchFinderView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CAStarPatchFinderDoc* CAStarPatchFinderView::GetDocument() const // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAStarPatchFinderDoc)));
	return (CAStarPatchFinderDoc*)m_pDocument;
}
#endif //_DEBUG

void CAStarPatchFinderView::Serialize(CArchive& ar)
{
	if (!ar.IsStoring())
	{
		game_map_.LoadMap(ar);
		CString file_path = ar.GetFile()->GetFilePath();
		file_path.Replace(_T(".asmp"), _T(".bmp"));
		picture_.Load(file_path);
	}
}
// CAStarPatchFinderView message handlers

BOOL CAStarPatchFinderView::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}

void CAStarPatchFinderView::OnLButtonDown(UINT nFlags, CPoint point)
{
	if (!game_map_.is_empty())
	{
		if (key_down(VK_CONTROL))
		{
			game_map_.set_start(point + offset_);
		}
		else
		{
			game_map_.set_end(point + offset_);
			game_map_.FindPath();
		}
	}

	Invalidate(TRUE);
	UpdateWindow();

	CView::OnLButtonDown(nFlags, point);
}

void CAStarPatchFinderView::OnRButtonDown(UINT nFlags, CPoint point)
{
	HCURSOR cursor_handle = LoadCursor(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDC_CURSOR_HAND_HOLD));
	SetCursor(cursor_handle);

	start_point_ = point;

	Invalidate(TRUE);
	UpdateWindow();

	CView::OnRButtonDown(nFlags, point);
}

void CAStarPatchFinderView::OnRButtonUp(UINT nFlags, CPoint point)
{
	if (!game_map_.is_empty())
	{
		offset_ += (start_point_ - point);
		offset_.x = max(offset_.x, 0);
		offset_.y = max(offset_.y, 0);

		CRect rc;
		GetClientRect(&rc);

		offset_.x = min(offset_.x, game_map_.get_width() - rc.Width());
		offset_.y = min(offset_.y, game_map_.get_height() - rc.Height());

		Invalidate(TRUE);
		UpdateWindow();
	}

	CView::OnRButtonUp(nFlags, point);
}

void CAStarPatchFinderView::OnMouseMove(UINT nFlags, CPoint point)
{
	if (!game_map_.is_empty())
	{
		CRect rc;
		GetClientRect(&rc);
		if (rc.PtInRect(point))
		{
			switch(nFlags)
			{
			case MK_RBUTTON:
				{
					HCURSOR cursor_handle = LoadCursor(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDC_CURSOR_HAND_HOLD));
					SetCursor(cursor_handle);

					OnRButtonUp(nFlags, point);

					start_point_ = point;

					break;
				}
			}
		}
	}

	CView::OnMouseMove(nFlags, point);
}
